package com.tsinkai.ettp.practice;

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;

import javax.crypto.Cipher;

import org.apache.commons.codec.binary.Base64;

public class RSAPra {
	
	private static String src = "hello world";
	
	public static void main(String[] args) {
		jdkRSA();
	}
	
	public static void jdkRSA() {
		try {
			//1、初始化秘钥
			KeyPairGenerator  keyPairGenerator = KeyPairGenerator.getInstance("RSA");
			keyPairGenerator.initialize(2048);//可加密长度2048bit/8=256byte,再根据填充方式(RSA/ECB/OAEPPadding)-41=215(实际214）
			KeyPair keyPair = keyPairGenerator.generateKeyPair();
			RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
			System.out.println("mou:"+rsaPublicKey.getModulus().bitLength());
			RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
			System.out.println("public key:" + Base64.encodeBase64String(rsaPublicKey.getEncoded()));
			
			System.out.println("pravate key:" + Base64.encodeBase64String(rsaPrivateKey.getEncoded()));
			
			//2、私钥加密、公钥解密——加密
			PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
			Cipher cipher = Cipher.getInstance("rsa");
			cipher.init(Cipher.ENCRYPT_MODE,privateKey);
			byte[] result  = cipher.doFinal(src.getBytes());
			System.out.println("私钥加密、公钥解密——加密：" + Base64.encodeBase64String(result));
			
			//3、私钥加密、公钥解密——解密
			X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
			keyFactory = KeyFactory.getInstance("RSA");
			PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
			cipher = Cipher.getInstance("RSA");
			cipher.init(Cipher.DECRYPT_MODE, publicKey);
			result = cipher.doFinal(result);
			System.out.println("私钥加密、公钥解密——解密：" + new String(result));
			
			//4、公钥加密、私钥解密——加密
			//将ras公钥钥转化为公钥
			x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
			keyFactory = KeyFactory.getInstance("RSA");
			publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
			//加密
			//加密填充方式可用参数
			//RSA/ECB/NoPadding
			//RSA/ECB/PKCS1Padding
			//RSA/ECB/OAEPPadding
			//
			cipher = Cipher.getInstance("RSA/ECB/OAEPPadding");
			cipher.init(Cipher.ENCRYPT_MODE, publicKey);
			result = cipher.doFinal(src.getBytes());
			System.out.println("公钥加密、私钥解密——加密：" + Base64.encodeBase64String(result));
			//5、公钥加密、私钥解密——解密
			pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
			keyFactory = KeyFactory.getInstance("RSA");
			privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
			cipher = Cipher.getInstance("RSA/ECB/OAEPPadding");
			cipher.init(Cipher.DECRYPT_MODE,privateKey);
			result  = cipher.doFinal(result);
			System.out.println("公钥加密、私钥解密——解密：" + new String(result));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
